package com.lingx.jt808.msg;

import com.lingx.jt808.IJT808MsgHandler;
import com.lingx.jt808.msg.x0200.IAttached;
import com.lingx.jt808.server.netty.Utils;
import com.lingx.jt808.utils.CoordinateConversion;
import io.netty.buffer.ByteBuf;
import io.netty.channel.ChannelHandlerContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

import javax.annotation.Resource;
import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

@Component
public class Msg0200 extends AbstrctMsgHandler implements IJT808MsgHandler {

    private static final Logger log = LoggerFactory.getLogger(Msg0200.class.getSimpleName());

    @Resource
    private List<IAttached> listAttached;

    @Override
    public int getMsgId() {
        return 0x0200;
    }

    @Override
    public String getTag() {
        return "[0200]位置信息汇报";
    }

    @Override
    public void handle(ByteBuf data, String tid, int msgId, int msgSn, ChannelHandlerContext ctx, boolean isVersion) {
        if (tid.trim().isEmpty()) {
            log.info("0200 tid empty");
            return;
        }
        Map<String, Object> map = new HashMap<>();
        long bj = data.readUnsignedInt();
        long zt = data.readUnsignedInt();
        double lat = data.readUnsignedInt() / 1000000f;
        double lng = data.readUnsignedInt() / 1000000f;
        int height = data.readUnsignedShort();
        int speed = data.readUnsignedShort();
        int fx = data.readUnsignedShort();
        byte[] bytes = new byte[6];
        data.readBytes(bytes);
        String gpstime = "20" + Utils.bytesToHex(bytes);
        map.put("tid", tid);
        map.put("type", "0x0200");
        map.put("alarm", bj);
        map.put("status", zt);
        map.put("lat", lat);
        map.put("lng", lng);
        map.put("height", height);
        map.put("speed", speed / 10f);
        map.put("direction", fx);
        map.put("gpstime", gpstime);
        map.put("systemtime", Utils.getTime());
        map.put("ts", System.currentTimeMillis());

        // 检测数据是否有效
        if (!CoordinateConversion.checkLoLa(String.format("%.5f", lng), String.format("%.5f", lat))) {
            log.info("0200 location error {}", tid);
            return;
        }

        boolean valid = true;
        DateFormat sdf = new SimpleDateFormat("yyyyMMddHHmmss");
        sdf.setLenient(false);
        try {
            sdf.parse(gpstime);
        } catch (Exception e) {
            log.info("0200 datetime error {}", tid);
            valid = false;
        }

        if (fx > 360) {
            log.info("0200 direction error {}", tid);
            valid = false;
        }

        if (speed >= 2000) {
            log.info("0200 speed error {}", tid);
            valid = false;
        }

        if (height >= 4000) {
            log.info("0200 height error {}", tid);
            valid = false;
        }

        if ((zt & 0b10) != 2) {
            log.info("0200 status location failure {}", tid);
            valid = false;
        }

        if (valid) {
            //在这里把网关ID传到处理器
            int aid, alen;
            while (data.readableBytes() > 0) {
                aid = data.readByte();
                alen = data.readByte();
                bytes = new byte[alen];
                data.readBytes(bytes);
                for (IAttached temp : this.listAttached) {
                    if (temp.getAttachedId() == aid) {
                        map.put(String.format("A%02x", aid), temp.getValue(bytes, tid));
                        break;
                    }
                }
            }
        }

        this.databaseService.handler0200(tid, map, valid);
    }
}
